package src.server;

import src.config.SysConfig;
import src.mysql.ScoreSqlHelper;


import java.net.Socket;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author CsCN
 * 懒汉式对战数据服务器
 * 功能:
 * 1. 开始联机对战.
 * 首先发送字符串match, 后跟游戏难度字符, 包括matchE, matchN, matchH
 * 然后发送用户名字符串
 * 游戏开始后, 会收到start字符串
 * 2. 获取指定难度的联机对战榜
 */
public class ScoreServer extends AbstractServer {

    private final static ScoreServer instance = new ScoreServer();
    public static ScoreSqlHelper scoreSqlHelper;
    /**
     * 等待者列表, 该难度无人则为null, 有人则为一个SocketHelper
     */
    private Map<ScoreSqlHelper.Difficulty, SocketHelper> waitingGroup = new HashMap<>();

    public static ScoreServer getInstance() {
        return instance;
    }

    private ScoreServer() {
        super(SysConfig.SERVER_PORT);
        // 初始化等待列表
        for (ScoreSqlHelper.Difficulty d : ScoreSqlHelper.Difficulty.values()) {
            waitingGroup.put(d, null);
        }
        // 初始化SqlHelper
        try {
            scoreSqlHelper = new ScoreSqlHelper();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("SQLHelper初始化失败");
            SysConfig.MYSQL_START = 0;
        }
    }

    @Override
    public void startThread(Socket socket) {
        if (SysConfig.MYSQL_START == 1) {
            new Thread(() -> scoreServerHandler(socket)).start();
        } else {
            try {
                socket.getInputStream().read();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void scoreServerHandler(Socket socket) {
        String request = SocketHelper.recvString(socket);
        System.out.println("recv String: " + request);
        if (request.startsWith("match")) {
            matchHandler(socket, ScoreSqlHelper.Difficulty.valueOf(String.valueOf(request.charAt(request.length() - 1))));
        } else if (request.startsWith("getData")) {
            getData(socket, ScoreSqlHelper.Difficulty.valueOf(String.valueOf(request.charAt(request.length() - 1))));
        } else {
            SocketHelper.sendString(socket, "???");
        }
    }

    /**
     * 尝试开始游戏
     *
     * @param socket     尝试联机对战的socket
     * @param difficulty 难度
     */
    public synchronized void matchHandler(Socket socket, ScoreSqlHelper.Difficulty difficulty) {
        // 初始化SocketHelper 获得用户名
        SocketHelper socketHelper = new SocketHelper(socket);
        socketHelper.sendString("OK");
        socketHelper.tag = socketHelper.recvString();
        System.out.println("received name: " + socketHelper.tag);

        // 获取等待列表信息
        SocketHelper wait = waitingGroup.get(difficulty);
        if (wait == null) {
            // 无人则开始等待
            waitingGroup.replace(difficulty, socketHelper);
        } else {
            // 有人则清空等待, 进入游戏
            waitingGroup.replace(difficulty, null);
            System.out.println("Entering game");
            new Thread(new MatchThread(socketHelper, wait, difficulty)).start();
        }
    }

    public void getData(Socket socket, ScoreSqlHelper.Difficulty difficulty) {
        int limit = 20;
        List<ScoreObj> tmp = scoreSqlHelper.getScore(difficulty, limit);
//        System.out.println("send: " + tmp.toString());
        SocketHelper.sendObject(socket, tmp);
    }
}
